package com.quanwe.common.util

import android.content.Context
import android.content.Intent
import android.os.Looper
import android.telephony.TelephonyManager
import android.util.Log
import android.widget.TextView
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import com.quanwe.common.base.App
import com.quanwe.common.net.API
import com.quanwe.common.net.APIManager
import com.quanwe.common.net.BaseBean
import com.quanwe.common.net.MobAPI
import com.quanwe.common.util.FrameworkSetting.LOG_LEVEL
import com.quanwe.common.util.LEVEL.*
import org.jetbrains.anko.doAsync
import org.jetbrains.anko.uiThread
import retrofit2.Call
import java.io.IOException
import java.io.Serializable
import java.text.SimpleDateFormat
import java.util.*

/**
 * 扩展方法集
 * Created by weiquan on 2017/6/22.
 */


/**
 * 打印日志
 * @param message 消息內容
 * @param level 消息級別
 * 兩種使用方法
 * _Log(日誌信息,日誌等級)
 * 日誌信息._Log(level=D)
 */
fun Any._Log(message: Any? = null, level: LEVEL = _D) {
    if (LOG_LEVEL == _NONE) return
    val logMessage = message ?: this.toString()
    when (level) {
        _D -> Log.d(javaClass.simpleName, "$logMessage")
        _E -> Log.e(javaClass.simpleName, "$logMessage")
        _I -> Log.i(javaClass.simpleName, "$logMessage")
        _V -> Log.v(javaClass.simpleName, "$logMessage")
        _W -> Log.w(javaClass.simpleName, "$logMessage")
        _A -> Log.wtf(javaClass.simpleName, "$logMessage")
    }
}

/**
 * 字符串转Bean
 */
inline fun <reified T> String.toBean(): T = Gson().fromJson(this, object : TypeToken<T>() {}.type)

/**
 * 对象转json
 */
fun Any.toJson(): String = GsonBuilder().create().toJson(this)

/**
 * 判断为空
 */
fun <T> T?.empty(callback: () -> Unit = {}): Boolean {
    when (true) {
        this == null,
        (this is TextView && this.text.toString().trim().isEmpty()),
        (this is String && this.length == 0),
        (this is List<*> && this.size == 0),
        (this is Map<*, *> && this.size == 0),
        (this is MutableMap<*, *> && this.size == 0),
        (this is MutableList<*> && this.size == 0),
        (this is Array<*> && this.size == 0) -> {
            callback.invoke()
            return true
        }

    }
    return false
}

/**
 * 判断非空
 */
fun <T> T?.notEmpty(callback: (T) -> Unit = {}): Boolean {
    if (!this.empty()) {
        callback.invoke(this as T)
        return true
    }
    return false
}

fun Long.date(): String {
    return try {
        SimpleDateFormat("yyyy-MM-dd hh:mm:ss").format(Date(this))
    } catch (e: Exception) {
        e.printStackTrace()
        ""
    }
}

inline operator fun <reified T> Intent.get(key: String): T {
    when (T::class.java) {
        String::class.java -> getStringExtra(key)
        Int::class.java -> getIntExtra(key, 0)
        Long::class.java -> getLongExtra(key, 0)
        Short::class.java -> getShortExtra(key, 0)
        Byte::class.java -> getByteExtra(key, 0)
        Boolean::class.java -> getBooleanExtra(key, false)
        Serializable::class.java -> getSerializableExtra(key)
    }
    throw RuntimeException("该类型不支持使用Intent存取")
}

inline fun <reified T> getRawType() = T::class.java

fun <T> T.ifrun(bool: Boolean = true, block: T.() -> Unit) {
    if (bool)
        block()
}

/**
 * 网络请求的成功回调
 */
fun <T : BaseBean<U>, U> Call<T>.isOK(callback: BaseBean<U>.() -> Unit) {
    val body = execute().body()
    if (body != null && body.success()) {
        callback(body)
    } else {
        callback(BaseBean { msg = "网络请求失败" })
    }
}


fun <U> BaseBean<U>.success(): Boolean = this?.status == 1 || this?.status == 200
/**
 * 网络请求的成功回调
 */
fun <T : BaseBean<U>, U> Call<T>.isAsynOK(callback: BaseBean<U>.() -> Unit) {
    if (Looper.getMainLooper() == Looper.myLooper()) {
        //不再
        doAsync {
            val body = execute().body()
            uiThread {
                if (body != null && body.success()) {
                    callback(body)
                } else {
                    callback(BaseBean { msg = "网络请求失败" })
                }
            }
        }
    } else {
        isOK(callback)
    }
}

/**
 * 迭代集合,暴露item内部
 */
fun <T> Iterable<T>.innerforEach(callback: T.() -> Unit) {
    for (item in this) {
        callback(item)
    }
}


/**
 * 设备号
 */
val _DEVICE_NO: String by lazy {
    val systemService = _CONTEXT.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
    systemService.deviceId
}


/**
 * 为所有类扩展上下文字段，即全局上下文
 */
val _CONTEXT: App get() = App._CONTEXT

/**
 * 全局接口请求对象
 */
val api: API get() = APIManager.request
val mobApi: MobAPI get() = APIManager.mobApi


